package cc.iotkit.manager.controller.report;

import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.excel.utils.ExcelUtil;
import cc.iotkit.common.log.annotation.Log;
import cc.iotkit.common.log.enums.BusinessType;
import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.data.constants.KeyConstants;
import cc.iotkit.manager.dto.bo.device.DeviceLogQueryBo;
import cc.iotkit.manager.dto.bo.report.DoorAccessRecordBo;
import cc.iotkit.manager.dto.vo.record.DoorAccessRecordVo;
import cc.iotkit.manager.dto.vo.record.EnergyRecordVo;
import cc.iotkit.manager.dto.vo.record.TemperatureHumidityRecordVo;
import cc.iotkit.manager.service.DoorAccessRecordService;
import cc.iotkit.manager.service.IDeviceManagerService;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.report.DoorAccessRecord;
import cc.iotkit.model.report.EnergyRecord;
import cc.iotkit.model.report.TemperatureHumidityRecord;
import cc.iotkit.temporal.IThingModelMessageData;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 能耗记录
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/report/energyReport")
@Slf4j
public class EnergyRecordController {

    @Autowired
    private IDeviceManagerService deviceServiceImpl;
    private static Validator validator;

    @Autowired
    private IThingModelMessageData thingModelMessageData;

    static {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }


    @ApiOperation(value = "获取能耗记录记录列表", notes = "获取能耗记录记录列表,根据查询条件分页")
    @SaCheckPermission("iot:energyReport:list")
    @PostMapping("/list")
    public Paging<EnergyRecordVo> list(@RequestBody @Validated PageRequest<EnergyRecord> query) {
        EnergyRecord record = query.getData();

        List<DeviceInfo> deviceInfoVoList = deviceServiceImpl.findByPk(KeyConstants.energyProductKey);
        ;
        List<String> devIds = deviceInfoVoList.stream().map((deviceInfoVo -> deviceInfoVo.getDeviceId())).collect(Collectors.toList());

        PageRequest<DeviceLogQueryBo> request = new PageRequest<>(query.getPageSize(), query.getPageNum(), query.getSortMap());
        DeviceLogQueryBo deviceLogQueryBo = new DeviceLogQueryBo();
        deviceLogQueryBo.setType("property");
        deviceLogQueryBo.setIdentifier("report");

        deviceLogQueryBo.setTimeStart(record.getDateTimeBegin() == null ? 0 : record.getDateTimeBegin().getTime());
        deviceLogQueryBo.setTimeEnd(record.getDateTimeEnd() == null ? 0 : record.getDateTimeEnd().getTime());
        request.setData(deviceLogQueryBo);
        Paging<ThingModelMessage> thingModelMessagePaging = thingModelMessageData.findByTypeAndDeviceIds(devIds, ThingModelMessage.TYPE_PROPERTY,
                "report", query.getPageNum(), query.getPageSize(),
                deviceLogQueryBo.getTimeStart(),
                deviceLogQueryBo.getTimeEnd());

        Paging<EnergyRecordVo> energyRecordVoPaging = new Paging<>();
        ArrayList<EnergyRecordVo> energyRecordVos = new ArrayList<>();

        energyRecordVoPaging.setTotal(thingModelMessagePaging.getTotal());
        for (ThingModelMessage thingModelMessage : thingModelMessagePaging.getRows()) {
            DeviceInfo deviceInfo = deviceServiceImpl.getDetail(thingModelMessage.getDeviceId());
            EnergyRecordVo recordVo = new EnergyRecordVo();
            recordVo.setThingModelMessage(thingModelMessage);
            recordVo.setDevice(deviceInfo);
            energyRecordVos.add(recordVo);
        }
        energyRecordVoPaging.setRows(energyRecordVos);

        return energyRecordVoPaging;
    }

    @Log(title = "能耗记录记录", businessType = BusinessType.EXPORT)
    @ApiOperation(value = "导出能耗记录记录列表", notes = "导出能耗记录记录列表")
    @SaCheckPermission("iot:energyReport:export")
    @PostMapping("/export")
    public void export(@Validated @RequestParam String data, HttpServletResponse response) {


        TemperatureHumidityRecord record = JsonUtils.parse(data, TemperatureHumidityRecord.class);


        List<DeviceInfo> deviceInfoVoList = deviceServiceImpl.findByPk(KeyConstants.energyProductKey);
        ;
        List<String> devIds = deviceInfoVoList.stream().map((deviceInfoVo -> deviceInfoVo.getDeviceId())).collect(Collectors.toList());


        DeviceLogQueryBo deviceLogQueryBo = new DeviceLogQueryBo();
        deviceLogQueryBo.setType("property");
        deviceLogQueryBo.setIdentifier("report");

        deviceLogQueryBo.setTimeStart(record.getDateTimeBegin() == null ? 0 : record.getDateTimeBegin().getTime());
        deviceLogQueryBo.setTimeEnd(record.getDateTimeEnd() == null ? 0 : record.getDateTimeEnd().getTime());

        List<ThingModelMessage> thingModelMessagePaging = thingModelMessageData.findByTypeAndDeviceIdsAll(devIds, ThingModelMessage.TYPE_PROPERTY,
                "report", deviceLogQueryBo.getTimeStart(), deviceLogQueryBo.getTimeEnd());


        ArrayList<EnergyRecordVo> energyRecordVos = new ArrayList<>();

        for (ThingModelMessage thingModelMessage : thingModelMessagePaging) {
            DeviceInfo deviceInfo = deviceServiceImpl.getDetail(thingModelMessage.getDeviceId());
            EnergyRecordVo recordVo = new EnergyRecordVo();
            recordVo.setThingModelMessage(thingModelMessage);

            recordVo.setFloor(deviceInfo.getFloor());
            recordVo.setPositionName(deviceInfo.getPosition() == null ? "" : deviceInfo.getPosition().getName());
            recordVo.setDeviceName(deviceInfo.getDeviceName());
            recordVo.setDateTime(thingModelMessage.getTime() == null ? null : new Date(thingModelMessage.getTime()));

            if (thingModelMessage.getData() != null) {
                Map thingData = (Map) thingModelMessage.getData();
                recordVo.setHz(thingData.get("Hz") == null ? null : (Float.parseFloat(thingData.get("Hz").toString())));
                try {
                    recordVo.setPhaseVoltageA(thingData.get("phaseVoltage_a") == null ? null : (Float.parseFloat(thingData.get("phaseVoltage_a").toString())));
                    recordVo.setPhaseVoltageB(thingData.get("phaseVoltage_b") == null ? null : (Float.parseFloat(thingData.get("phaseVoltage_b").toString())));
                    recordVo.setPhaseVoltageC(thingData.get("phaseVoltage_c") == null ? null : (Float.parseFloat(thingData.get("phaseVoltage_c").toString())));
                    recordVo.setVoltageA(thingData.get("voltage_a") == null ? null : (Float.parseFloat(thingData.get("voltage_a").toString())));
                    recordVo.setVoltageB(thingData.get("voltage_b") == null ? null : (Float.parseFloat(thingData.get("voltage_b").toString())));
                    recordVo.setVoltageC(thingData.get("voltage_c") == null ? null : (Float.parseFloat(thingData.get("voltage_c").toString())));
                    recordVo.setElectricEnergy(thingData.get("electricEnergy") == null ? null : (Float.parseFloat(thingData.get("electricEnergy").toString())));
                    recordVo.setElectricityA(thingData.get("electricity_a") == null ? null : (Float.parseFloat(thingData.get("electricity_a").toString())));
                    recordVo.setElectricityB(thingData.get("electricity_b") == null ? null : (Float.parseFloat(thingData.get("electricity_b").toString())));
                    recordVo.setElectricityC(thingData.get("electricity_c") == null ? null : (Float.parseFloat(thingData.get("electricity_c").toString())));
                    recordVo.setPower(thingData.get("power") == null ? null : (Float.parseFloat(thingData.get("power").toString())));
                } catch (Exception pe) {
                    log.error("提取数据失败：", pe);
                    log.error(JsonUtils.toJsonString(thingData));
                }


            }

            recordVo.setDevice(deviceInfo);
            energyRecordVos.add(recordVo);
        }

        ExcelUtil.exportExcel(energyRecordVos, "能耗记录", EnergyRecordVo.class, response);
    }


}
